/* jshint esversion: 8 */
/*jshint -W069 */
//const logger = require("./logger.js");

//在线的WS客户端连接储存到this.onlines中
class WssClients {
    constructor() {
        this.onlines = {}; //在线的连接{"1": {WsClient对象}}
        this.onlinePlayers = {}; //同步服务器在线的玩家 {"BDSUid": {ServerName:"FlySteve", players:["Wn1027"]}}
        this.usedUid = 0;
    }

    // 获取在线连接数
    get num(){
        return Object.keys(this.onlines).length;
    }

    // 获取同步服务器的主服务器连接
    get syncMainBDS(){
        let mainBDS;
        let mainNum = 0;
        this.forEach((client) => {
            if (client.BDSType == 'main'){
                mainBDS = client;
                mainNum ++;
            }
        });
        if (mainNum == 1){
            return mainBDS;
        }else{
            return null;
        }
    }

    // 获取在线连接的所有名字
    // return flysteve(1), ziyuan(2)
    get OnlineNames(){
        let onlines = [];
        this.forEach((client) =>(onlines.push(`${client.name}(${client.uid})`)));
        return onlines.join(", ");
    }


    // 向在线的所有BDS更新云端在线BDS的信息
    refOnlineBDSInfo(){
        let result = {
            serverConfig:{
                SyncInventoryDB: SyncInventoryDB,
                SyncMode: SyncMode
            }, 
            onlineBDSInfo:{}
        };
        this.forEach((client) =>{
            if (client.userType == "server"){
                result.onlineBDSInfo[client.BDSUid] = {
                    uid: client.uid,
                    ServerName: client.name,
                    BDSType: client.BDSType,
                    BDSUid: client.BDSUid,
                    BDSIp: client.BDSIp,
                    BDSPort: client.BDSPort,
                };
            }
        });
        this.forEach((client) =>{
            if (client.userType == "server"){
                client.sendJson(result, "refOnlineBDSInfo");
            }
        });
    }

    // 预登录检查（多设备检查）
    playerPreLogin(client, playerRealName){
        for (let key in this.onlines){
            let clientData = this.onlinePlayers[this.onlines[key].BDSUid];
            if (clientData == undefined){
                continue; //排除非BDS服务器
            }
            if (clientData.players.includes(playerRealName)){
                return false;
            }
        }
        return true;
    }

    // 同步服务器玩家登记
    playerLogin(client, playerRealName){
        if (this.onlinePlayers[client.BDSUid] == undefined){
            this.onlinePlayers[client.BDSUid] = {ServerName: client.name, players:[playerRealName]};
        }else{
            this.onlinePlayers[client.BDSUid].players.push(playerRealName);
        }
        return true;
    }

    // 同步服务器玩家登出
    playerLogout(client, playerRealName){
        let result = false;
        for (let key in this.onlines){
            let clientData = this.onlinePlayers[this.onlines[key].BDSUid];
            if (clientData == undefined){
                continue;
            }

            if (clientData.players.includes(playerRealName)){
                clientData.players.splice(clientData.players.indexOf(playerRealName), 1);
                if (clientData.players.length == 0){
                    delete this.onlinePlayers[this.onlines[key].BDSUid];
                }
                result = true;
            }

        }
        return result;

    }

    // 添加客户端连接
    add(client) {
        if (client.uid != undefined){
            this.onlines[client.uid] = client;
            this.usedUid ++;
            return true;
        }else{
            return false;
        }
        
    }

    // 移除客户端连接
    remove(client) {
        if (this.onlines[client.uid] != undefined){
            delete this.onlines[client.uid];
            delete this.onlinePlayers[client.BDSUid];
            return true;
        }else{
            return false;
        }
    }

    // 获取指定UID的客户端连接
    getClient_uid(uid){
        for (let clientUid in this.onlines){
            if (this.onlines[clientUid].uid == uid){		
                return this.onlines[clientUid];
            }
        }
        return null;
    }

    // 广播消息
    broadcast(msg, tag, uninclude){
        for (let client in this.onlines){
            if (uninclude != undefined){
                if (uninclude.indexOf(this.onlines[client].uid) != -1){
                    continue;
                }
            }
            this.onlines[client].sendText(msg, tag);
        }
    }

    // 广播json消息
    broadcastJson(data, purpose, uninclude){
        this.forEach((client) =>{
            if (uninclude != undefined){
                if (uninclude.indexOf(client.uid) != -1){
                    return;
                }
            }
            client.sendJson(data, purpose);
        });
    }

    // 为每个客户端连接执行函数 （目前仅用于获取在线客户端名称列表）
    forEach(func){
        for (let client in this.onlines){
            func(this.onlines[client]);
        }
    }
}

class WsClient {
    //本类需要有全局变量 Clients
    constructor(uid, ws){
        this.uid = uid;
        this.initState = 0; //初始化状态
        this.ws =  ws;  // 该玩家的ws连接
        this.name = "user"; // 玩家昵称
        this.userType = "client"; //'client' or 'server'
        this.BDSType = 'sub'; // 'main' or 'sub' 仅在userType为 'server' 的情况下有效
        this.BDSUid = ''; // BDS唯一识别名
        this.BDSIp = ''; // 仅在userType为 'server' 的情况下有效
        this.BDSPort = 19132; // 仅在userType为 'server' 的情况下有效
        this.progress = 0; 
        this.locPos = {x:0,y:65,z:0};
        this.mapcolor = [];
        this.ChunkStep = 64;
        this.fail = 0;
        this.tasking = false;
    }

    test(){
        console.log("WsClient func exec success");
    }

    //云端命令函数
    runcmd(cmd, tag = "") {
        let json = {
            "body": {
                "commandLine": cmd,
                "version": 1
            },
            "header": this.buildHeader("commandRequest", tag)
        };      
        this.ws.send(JSON.stringify(json));	    
    }

    //聊天消息函数
    sendText(msg, tag = "") {
        let json = {
            "body": {
                "commandLine": "tellraw @a {\"rawtext\":[{\"text\":\"" + msg + "\"}]}",
                "version": 1
            },
            "header": this.buildHeader("commandRequest", tag)
        };  
        this.ws.send(JSON.stringify(json));
    }


    // 发送普通目的Json消息
    sendJson(data, purpose){
        let json = {
            "body": {
                "data": data,
                "version": 1
            },
            "header": this.buildHeader(purpose)
        };
        this.ws.send(JSON.stringify(json));
    }

    //订阅事件函数
    subscribe(eventName) {
        let json = {
            "body": {
                "eventName": eventName
            },
            "header": this.buildHeader("subscribe")
        };
        this.ws.send(JSON.stringify(json));
        //logger.info("[新成员订阅事件]" + eventName + " Uid:" + this.uid);
    }

    //执行mcfunction
    async runFunction(func, delay) {
        for (let i = 0; i< func.length; i++){
            if (this.tasking == false || this.tasking  == undefined){
                this.progress = 0;
                return;
            }
            if (func[i].split(" ")[0] == "delay"){
                await this.sleep(Number(func[i].split(" ")[1]));
            }else{
                this.runcmd(func[i], func[i]);
                await this.sleep(delay);
            }
            this.progress = (((i+1)/func.length)*100).toFixed(2);
        }
        this.progress = 0;
        this.tasking  = false;
        //this.sendText(`${tipHeader} 命令执行完毕`);
    }


    

    //只在本类中调用
    buildHeader(purpose, tag = "") {
        return {
            requestId: tag+"@"+this.uid,
            messagePurpose: purpose,
            version: 1,
            messageType: 'commandRequest'
        };
    }

    async sleep(time) {
          return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve();
            }, time);
          });
    }

}

module.exports = {
    WssClients,
    WsClient
};
